{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b17d2f53",
   "metadata": {},
   "source": [
    "# OFRAK Tutorial\n",
    "\n",
    "The Open Firmware Reverse Analysis Konsole (OFRAK) is a modular framework that allows users to programmatically analyze, reverse engineer, and modify binaries."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42cbf1e7",
   "metadata": {},
   "source": [
    "## Tutorial overview"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "baa04612",
   "metadata": {},
   "source": [
    "The goal of this tutorial is to help you understand how OFRAK works and how to use it, while interactively showcasing some of its main features.\n",
    "\n",
    "No prior knowledge of OFRAK is required. Basic Python and reverse-engineering knowledge will help.\n",
    "\n",
    "This tutorial is organized in a number of lessons. It's recommended to go through them in order, as lessons gradually build on top of each other, from the simplest examples to advanced capabilities of OFRAK.\n",
    "\n",
    "From any lesson, you can navigate to the next one using the \"Next page\" link at the bottom of the page.\n",
    "\n",
    "You don't need to change any code for the examples to work, but you do need to run all Python cells in order to see their outputs.\n",
    "\n",
    "Below are the objectives for each lesson. The OFRAK-specific vocabulary will be introduced as needed.\n",
    "\n",
    "- [Lesson 1: Simple string modification](1_simple_string_modification.ipynb) − manipulate the data of a resource; run a modifier; flush a modified resource to disk\n",
    "- [Lesson 2: A closer look into OFRAK unpacking and the resource tree](2_ofrak_internals.ipynb) − unpack a resource; learn about OFRAK components; learn about auto-analysis, tags, and the resource tree; filter the resource tree\n",
    "- [Lesson 3: Binary format modification](3_binary_format_modification.ipynb) − learn about resource views; find specific children in a resource tree and modify them; manipulate ELF program headers\n",
    "- [Lesson 4: In-place instruction rewriting](4_simple_code_modification.ipynb) − use OFRAK's Ghidra backend; use more filtering capabilities to find specific complex blocks and instructions; assemble an instruction using Keystone; rewrite an instruction in-place\n",
    "- [Lesson 5: Filesystem modification](5_filesystem_modification.ipynb) − learn about OFRAK's filesystem unpacking and modification capabilities; modify a binary from within a filesystem and the filesystem itself\n",
    "- [Lesson 6: Code extension by adding a new segment in the ELF](6_code_insertion_with_extension.ipynb) − add a new segment in an ELF; use the OFRAK PatchMaker to convert a C patch into a binary patch, including a linking step"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94613f73",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84406877",
   "metadata": {},
   "source": [
    "For this tutorial, we need a binary. Let's create one here from a simple C program:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1b496626",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.chdir(\"/tmp\")\n",
    "\n",
    "c_program = r\"\"\"\n",
    "#include <stdio.h>\n",
    "int main() {\n",
    "   printf(\"Hello, World!\\n\");\n",
    "   return 0;\n",
    "}\n",
    "\"\"\"\n",
    "\n",
    "with open(\"hello_world.c\", \"w\") as f:\n",
    "    f.write(c_program)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "37aae2ed",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, World!\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "gcc -no-pie -o hello_world hello_world.c\n",
    "\n",
    "./hello_world"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0e7f351",
   "metadata": {},
   "source": [
    "We're ready for analysis and modification now!\n",
    "\n",
    "We begin to use OFRAK by importing it and initializing the object that will load our binary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "eef6e91b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using OFRAK Community License.\n"
     ]
    }
   ],
   "source": [
    "import logging\n",
    "from ofrak import OFRAK\n",
    "\n",
    "ofrak = OFRAK()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8d121e8",
   "metadata": {},
   "source": [
    "Now that all of the components are loaded, we can create an OFRAK context. The OFRAK context is what lets different OFRAK scripts use the same database of analyzed data. The context is also what we will use to load in the initial firmware binary.\n",
    "\n",
    "Note that we use the `await` python keyword when creating the context. OFRAK includes many asynchronous functions that take advantage of the [Python event loop](https://docs.python.org/3/library/asyncio-eventloop.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c3eb3489",
   "metadata": {},
   "outputs": [],
   "source": [
    "basic_context = await ofrak.create_ofrak_context()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28aed732",
   "metadata": {},
   "source": [
    "It is now time to load our root resource. Resources are the core unit on which OFRAK operates. Resources can have children. For example, a resource representing a directory would have one child for each file in the directory. This parent-child relationship forms a structure informally referred to as the resource tree.\n",
    "\n",
    "A root resource is the parent resource of all other resources in the tree. Usually it is loaded as a file from disk."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0ee43d1d",
   "metadata": {},
   "outputs": [],
   "source": [
    "root_resource = await basic_context.create_root_resource_from_file(\"hello_world\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3e3981c",
   "metadata": {},
   "source": [
    "Before we go into into the details of the resource tree and OFRAK's unpacking capabilities, we can already perform our first task: let's replace \"Hello, World!\" with something a bit more fun and furry 😼. Meow!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cca54661",
   "metadata": {},
   "source": [
    "[Next page](1_simple_string_modification.ipynb)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
